package cn.smile.utils;

import cn.smile.commons.constant.NumberConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

@Slf4j
@Component
public class DataBaseConn {
    @Value("${spring.datasource.username}")
    public String username;
    @Value("${spring.datasource.password}")
    public String password;
    @Value("${spring.datasource.driver-class-name}")
    public String driverName;
    @Value("${spring.datasource.url}")
    public String url;
    Connection con;

    /**
     * 获取SQL执行对象
     *
     * @return sql执行对象
     */
    public Statement getStatement() {
        return this.getStatement(NumberConstant.ONE);
    }

    /**
     * 获取SQL执行对象
     *
     * @param executeNum 执行次数
     * @return sql执行对象
     */
    private Statement getStatement(int executeNum) {
        Connection conn = this.getConnection();
        Statement sta;
        try {
            sta = conn.createStatement();
        } catch (Exception e) {
            log.error("第 {} 次创建 SQL 连接失败, 正在重试", executeNum);
            this.getConnection(Boolean.TRUE);
            ++executeNum;
            sta = this.getStatement(executeNum);
        }
        return sta;
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接
     */
    public Connection getConnection() {
        return this.getConnection(Boolean.FALSE);
    }

    /**
     * 获取数据库连接
     *
     * @param isNew 重新创建连接
     * @return 数据库连接
     */
    private Connection getConnection(Boolean isNew) {
        try {
            if (ObjectUtils.isEmpty(con) || isNew) {
                con = this.createConn();
            }
        } catch (Exception e) {
            log.error("获取数据库连接异常, e: ", e);
        }
        return con;
    }

    /**
     * 创建数据库连接
     *
     * @return 数据库连接
     * @throws Exception 连接创建异常
     */
    private Connection createConn() throws Exception {
        try {
            Class.forName(driverName);
            log.info("数据库驱动加载成功");
        } catch (ClassNotFoundException e) {
            log.error("数据库驱动加载异常");
            throw e;
        }
        try {
            con = DriverManager.getConnection(url, username, password);
            log.info("数据库连接成功");
        } catch (SQLException e) {
            log.error("数据库连接异常");
            throw e;
        }
        return con;
    }
}
